home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 3
/
Cream of the Crop 3.iso
/
comm
/
wnos5src.zip
/
SERVER.C
< prev
next >
Wrap
Text File
|
1993-10-18
|
29KB
|
1,490 lines
/* Server start/stop functions */
/* Copyright 1991/2 Phil Karn, KA9Q */
#include <stdio.h>
#include <ctype.h>
#include "global.h"
#include "config.h"
#ifdef SERVERS
#include "socket.h"
#include "session.h"
#include "commands.h"
#include "remote.h"
#include "smtp.h"
#include "tcp.h" /* for kick() */
#include "files.h"
#include "dirutil.h"
#include "devparam.h"
#include "bbs.h"
#ifdef DNS
#include "domain.h"
#endif
#ifdef LZW
#include "lzw.h"
#endif
#ifdef CONVERS
#include "convers.h"
#endif
#ifdef MAILBOX
#include "mailbox.h"
#endif
#ifdef POP
#include "pop.h"
#endif
#ifdef NNTP
#include "nntp.h"
#endif
#if(defined(MODEM) && defined(ASY))
#include "asy.h"
#include "n8250.h"
#include "modem.h"
#include "usock.h"
int tip0 __ARGS((int argc,char **argv,void *));
static struct tipcb *Tiplist = NULLTIP;
#endif
#define DIFFTIME 2208988800L
static int SLoginwait = 0;
int Axi_sock = -1;
#ifdef CONVERS
static int SConv = -1;
#endif
static int SDisc = -1;
#ifdef DNS
static int SDomain = -1;
#endif
static int SEcho = -1;
static int SFinger = -1;
static int SFtp = -1;
#if (defined NETROM) && (defined MAILBOX)
static int SNetrom = -1;
#endif
#ifdef NNTP
static int SNntp = -1;
#endif
#ifdef POP
static int SPop = -1;
#endif
static int SRem = -1;
static int SSmtp = -1;
#ifdef MAILBOX
static int STelnet = -1;
#endif
static int STime = -1;
static int STtylink = -1;
#if (defined CONVERS) && (defined LZW)
static int SXConv = -1;
#endif
#if (defined CONVERS) && (defined LINK)
static struct proc *child = NULLPROC;
#endif
#define CSTACKSIZE 1024 /* Convers server stacksize */
#ifdef NETROM
#define MSTACKSIZE 4048 /* Mailbox stacksize */
#else
#define MSTACKSIZE 3072 /* Mailbox stacksize */
#endif
#ifdef UDP
char *Rempass = ""; /* Remote access password */
#endif
static int near chkrpass (struct mbuf *bp);
static void discserv (int s,void *unused,void *p);
static void echoserv (int s,void *unused,void *p);
static void fingerserv (int s,void *unused,void *p);
static void timeserv (int s,void *unused,void *p);
static void near
chpname(struct proc *pp,char *newname)
{
sprintf(pp->name,"%.16s",newname);
}
/* Wait for a signal that the RLSD modem status has changed */
static int near
get_rlsd_asy(int dev,int new_rlsd)
{
struct asy *ap = &Asy[dev];
if(ap->rlsd == 0) {
return -1;
}
for(;;) {
if(new_rlsd && (ap->msr & MSR_RLSD)) {
return 1;
}
if(!new_rlsd && !(ap->msr & MSR_RLSD)) {
return 0;
}
/* Wait for state change to requested value */
pause(2L);
pwait(&(ap->rlsd));
}
}
/* ---------------------- Server start functions ----------------------- */
/* Start up TCP discard server */
int
dis1(int argc,char **argv,void *p)
{
struct sockaddr_in lsocket;
int s;
if(SDisc != -1) {
return 0;
}
psignal(Curproc,0); /* Don't keep the parser waiting */
chpname(Curproc,"Discard listener");
lsocket.sin_family = AF_INET;
lsocket.sin_addr.s_addr = INADDR_ANY;
lsocket.sin_port = (argc < 2) ? IPPORT_DISCARD : atoi(argv[1]);
SDisc = socket(AF_INET,SOCK_STREAM,0);
bind(SDisc,(char *)&lsocket,SOCKSIZE);
listen(SDisc,1);
for(;;){
if((s = accept(SDisc,NULLCHAR,0)) == -1) {
/* Service is shutting down */
break;
}
if(availmem()) {
/* Spawn a server */
newproc("Discard server",576,discserv,s,0,0,0);
} else {
shutdown(s,1);
}
}
return 0;
}
/* Start up TCP echo server */
int
echo1(int argc,char **argv,void *p)
{
struct sockaddr_in lsocket;
int s;
if(SEcho != -1) {
return 0;
}
psignal(Curproc,0); /* Don't keep the parser waiting */
chpname(Curproc,"Echo listener");
lsocket.sin_family = AF_INET;
lsocket.sin_addr.s_addr = INADDR_ANY;
lsocket.sin_port = (argc < 2) ? IPPORT_ECHO : atoi(argv[1]);
SEcho = socket(AF_INET,SOCK_STREAM,0);
bind(SEcho,(char *)&lsocket,SOCKSIZE);
listen(SEcho,1);
for(;;){
if((s = accept(SEcho,NULLCHAR,0)) == -1) {
/* Service is shutting down */
break;
}
if(availmem()) {
/* Spawn a server */
newproc("Echo server",576,echoserv,s,0,0,0);
} else {
shutdown(s,1);
}
}
return 0;
}
#if (defined MAILBOX) && (defined AX25)
/* start up AX.25 Mailbox server */
int
ax25start(int argc,char **argv,void *p)
{
int s;
if(Axi_sock != -1) {
return 0;
}
psignal(Curproc,0); /* Don't keep the parser waiting */
chpname(Curproc,"AX25 listener");
Axi_sock = socket(AF_AX25,SOCK_STREAM,0);
/* bind() is done automatically */
listen(Axi_sock,1);
for(;;){
if((s = accept(Axi_sock,NULLCHAR,0)) == -1) {
/* Service is shutting down */
break;
}
if(availmem()) {
/* Spawn a server then eat the line that triggered the
* connection and then start the mailbox
*/
sockmode(s,SOCK_ASCII); /* To make recvline work */
recvline(s,NULLCHAR,80);
newproc("Mbox (AX25)",MSTACKSIZE,mbx_incom,s,(void *)AX25TNC,0,0);
} else {
shutdown(s,1);
}
}
return 0;
}
#endif
#if (defined MAILBOX) && (defined NETROM)
/* start up NETROM Mailbox server */
int
nr4start(int argc,char **argv,void *p)
{
int s;
if(SNetrom != -1) {
return 0;
}
psignal(Curproc,0); /* Don't keep the parser waiting */
chpname(Curproc,"NETROM listener");
SNetrom = socket(AF_NETROM,SOCK_SEQPACKET,0);
/* bind() is done automatically */
listen(SNetrom,1);
for(;;){
if((s = accept(SNetrom,NULLCHAR,0)) == -1) {
/* Service is shutting down */
break;
}
if(availmem()) {
/* Spawn a server */
newproc("Mbox (NR)",MSTACKSIZE,mbx_incom,s,(void *)NRSESSION,0,0);
} else {
shutdown(s,1);
}
}
return 0;
}
#endif
#ifdef MAILBOX
/* Start up Telnet server */
int
telnet1(int argc,char **argv,void *p)
{
struct sockaddr_in lsocket;
int s;
if(STelnet != -1) {
return 0;
}
psignal(Curproc,0); /* Don't keep the parser waiting */
chpname(Curproc,"Telnet listener");
lsocket.sin_family = AF_INET;
lsocket.sin_addr.s_addr = INADDR_ANY;
lsocket.sin_port = (argc < 2) ? IPPORT_TELNET : atoi(argv[1]);
STelnet = socket(AF_INET,SOCK_STREAM,0);
bind(STelnet,(char *)&lsocket,SOCKSIZE);
listen(STelnet,1);
for(;;){
if((s = accept(STelnet,NULLCHAR,0)) == -1) {
/* Service is shutting down */
break;
}
if(availmem()) {
/* Spawn a server */
newproc("Mbox (Telnet)",MSTACKSIZE,mbx_incom,s,(void *)TELNET,0,0);
} else {
shutdown(s,1);
}
}
return 0;
}
#endif
#ifdef UDP
/* Start remote exit/reboot server */
int
rem1(int argc,char **argv,void *p)
{
struct sockaddr_in lsocket, fsock;
int command;
struct mbuf *bp;
int32 addr = 0;
if(SRem != -1) {
return 0;
}
psignal(Curproc,0);
chpname(Curproc,"Remote listener");
lsocket.sin_family = AF_INET;
lsocket.sin_addr.s_addr = INADDR_ANY;
lsocket.sin_port = (argc < 2) ? IPPORT_REMOTE : atoi(argv[1]);
SRem = socket(AF_INET,SOCK_DGRAM,0);
bind(SRem,(char *)&lsocket,SOCKSIZE);
for(;;){
int i = SOCKSIZE;
if(recv_mbuf(SRem,&bp,0,(char *)&fsock,&i) == -1) {
break;
}
command = PULLCHAR(&bp);
i = chkrpass(bp);
switch(command){
case SYS_RESET:
log(SRem,9983,"REM reset %s %s",
psocket((struct sockaddr *)&fsock),i ? "" : "PASS FAIL");
if(i) {
void far (*foo) __ARGS((void));
/* FFFF:0000 is hardware reset vector */
foo = MK_FP(0xffff,0);
(*foo)();
}
break;
case SYS_EXIT:
log(SRem,9983,"REM exit %s %s",
psocket((struct sockaddr *)&fsock),i ? "" : "PASS FAIL");
if(i) {
char *arg[3];
arg[1] = "254";
doexit(0,arg,0);
}
break;
case KICK_ME:
if(len_p(bp) >= sizeof(int32)) {
addr = pull32(&bp);
} else {
addr = fsock.sin_addr.s_addr;
}
kick(addr);
smtptick((void *)addr);
break;
}
free_p(bp);
}
return 0;
}
#endif
#ifdef CONVERS
/* Start up convers server */
int
conv1(int argc,char **argv,void *p)
{
struct sockaddr_in lsocket;
int s;
if(SConv != -1) {
return 0;
}
psignal(Curproc,0); /* Don't keep the parser waiting */
chpname(Curproc,"Convers listener");
lsocket.sin_family = AF_INET;
lsocket.sin_addr.s_addr = INADDR_ANY;
lsocket.sin_port = (argc < 2) ? IPPORT_CONVERS : atoi(argv[1]);
SConv = socket(AF_INET,SOCK_STREAM,0);
bind(SConv,(char *)&lsocket,SOCKSIZE);
listen(SConv,1);
#ifdef LINK
if(child == NULLPROC) {
child = newproc("cperm",1024,connect_Permlink,0,0,0,0);
}
#endif
for(;;){
if((s = accept(SConv,NULLCHAR,0)) == -1) {
/* Service is shutting down */
break;
}
if(availmem()) {
/* Spawn a server */
newproc("Convers server",CSTACKSIZE,conv_incom,s,0,0,0);
} else {
shutdown(s,1);
}
}
return 0;
}
#endif
#if (defined CONVERS) && (defined LZW)
/* Start up xconvers server */
int
xconv1(int argc,char **argv,void *p)
{
struct sockaddr_in lsocket;
int s;
if(SXConv != -1) {
return 0;
}
psignal(Curproc,0); /* Don't keep the parser waiting */
chpname(Curproc,"XConv listener");
lsocket.sin_family = AF_INET;
lsocket.sin_addr.s_addr = INADDR_ANY;
lsocket.sin_port = (argc < 2) ? IPPORT_XCONVERS : atoi(argv[1]);
SXConv = socket(AF_INET,SOCK_STREAM,0);
bind(SXConv,(char *)&lsocket,SOCKSIZE);
listen(SXConv,1);
#ifdef LINK
if(child == NULLPROC) {
child = newproc("cperm",1024,connect_Permlink,0,0,0,0);
}
#endif
for(;;){
if((s = accept(SXConv,NULLCHAR,0)) == -1) {
/* Service is shutting down */
break;
}
if(availmem()) {
/* Spawn a server */
newproc("XConvers server",CSTACKSIZE,conv_incom,s,(void *)1,0,0);
} else {
shutdown(s,1);
}
}
return 0;
}
#endif
#ifdef DNS
/* start up Domain server */
int
dom1(int argc,char **argv,void *p)
{
struct sockaddr_in lsocket, from;
struct mbuf *bp;
if(SDomain != -1) {
return 0;
}
psignal(Curproc,0);
chpname(Curproc,"Domain listener");
lsocket.sin_family = AF_INET;
lsocket.sin_addr.s_addr = INADDR_ANY;
lsocket.sin_port = (argc < 2) ? IPPORT_DOMAIN : atoi(argv[1]);
SDomain = socket(AF_INET,SOCK_DGRAM,0);
bind(SDomain,(char *)&lsocket,SOCKSIZE);
for(;;){
struct dhdr *dhdr;
int i = SOCKSIZE;
if(recv_mbuf(SDomain,&bp,0,(char *)&from,&i) == -1) {
break;
}
dhdr = mxallocw(sizeof(struct dhdr));
ntohdomain(dhdr,&bp);
if(dhdr->qr != RESPONSE) {
struct Server *dp = mxallocw(sizeof(struct Server));
dp->address = from.sin_addr.s_addr;
dp->protocol = from.sin_port;
if(dhdr->opcode != ZONEINIT) {
newproc("Domain query",1024,proc_query,SDomain,(void *)dp,(void *)dhdr,0);
}
}
}
return 0;
}
#endif
/* Start up finger service */
int
fin1(int argc,char **argv,void *p)
{
struct sockaddr_in lsocket;
int s;
if(SFinger != -1) {
return 0;
}
psignal(Curproc,0); /* Don't keep the parser waiting */
chpname(Curproc,"Finger listener");
lsocket.sin_family = AF_INET;
lsocket.sin_addr.s_addr = INADDR_ANY;
lsocket.sin_port = (argc < 2) ? IPPORT_FINGER : atoi(argv[1]);
SFinger = socket(AF_INET,SOCK_STREAM,0);
bind(SFinger,(char *)&lsocket,SOCKSIZE);
listen(SFinger,1);
for(;;){
if((s = accept(SFinger,NULLCHAR,0)) == -1) {
/* Service is shutting down */
break;
}
if(availmem()) {
/* Spawn a server */
newproc("Finger server",1280,fingerserv,s,0,0,0);
} else {
shutdown(s,1);
}
}
return 0;
}
/* Start up FTP service */
int
ftp1(int argc,char **argv,void *p)
{
struct sockaddr_in lsocket;
int s;
if(SFtp != -1) {
return 0;
}
psignal(Curproc,0); /* Don't keep the parser waiting */
chpname(Curproc,"FTP listener");
lsocket.sin_family = AF_INET;
lsocket.sin_addr.s_addr = INADDR_ANY;
lsocket.sin_port = (argc < 2) ? IPPORT_FTP : atoi(argv[1]);
SFtp = socket(AF_INET,SOCK_STREAM,0);
bind(SFtp,(char *)&lsocket,SOCKSIZE);
listen(SFtp,1);
for(;;){
if((s = accept(SFtp,NULLCHAR,0)) == -1) {
/* Service is shutting down */
break;
}
if(availmem()) {
/* 421 Spawn a server */
newproc("FTP server",1536,ftpserv,s,0,0,0);
} else {
shutdown(s,1);
}
}
return 0;
}
#ifdef NNTP
/* Start up NNTP receiver service */
int
nntp1(int argc,char **argv,void *p)
{
struct sockaddr_in lsocket;
int s;
if(SNntp != -1) {
return 0;
}
psignal(Curproc,0); /* Don't keep the parser waiting */
chpname(Curproc,"NNTP listener");
lsocket.sin_family = AF_INET;
lsocket.sin_addr.s_addr = INADDR_ANY;
lsocket.sin_port = (argc < 2) ? IPPORT_NNTP : atoi(argv[1]);
SNntp = socket(AF_INET,SOCK_STREAM,0);
bind(SNntp,(char *)&lsocket,SOCKSIZE);
listen(SNntp,1);
for(;;){
if((s = accept(SNntp,NULLCHAR,0)) == -1) {
/* Service is shutting down */
break;
}
if(availmem()) {
/* 503 Spawn a server */
newproc("NNTP server",4048,nntpserv,s,0,0,0);
} else {
shutdown(s,1);
}
}
return 0;
}
#endif
#ifdef POP
/* Start up POP receiver service */
int
pop1(int argc,char **argv,void *p)
{
struct sockaddr_in lsocket;
int s;
if(SPop != -1) {
return 0;
}
psignal(Curproc,0); /* Don't keep the parser waiting */
chpname(Curproc,"POP listener");
lsocket.sin_family = AF_INET;
lsocket.sin_addr.s_addr = INADDR_ANY;
lsocket.sin_port = (argc < 2) ? IPPORT_POP : atoi(argv[1]);
SPop = socket(AF_INET,SOCK_STREAM,0);
bind(SPop,(char *)&lsocket,SOCKSIZE);
listen(SPop,1);
for (;;) {
if((s = accept(SPop,NULLCHAR,0)) == -1) {
/* Service is shutting down */
break;
}
if(availmem()) {
/* Spawn a server */
newproc("POP server",1536,popserv,s,0,0,0);
} else {
shutdown(s,1);
}
}
return 0;
}
#endif
/* Start up SMTP receiver service */
int
smtp1(int argc,char **argv,void *p)
{
struct sockaddr_in lsocket;
int s;
if(SSmtp != -1) {
return 0;
}
psignal(Curproc,0); /* Don't keep the parser waiting */
chpname(Curproc,"SMTP listener");
lsocket.sin_family = AF_INET;
lsocket.sin_addr.s_addr = INADDR_ANY;
lsocket.sin_port = (argc < 2) ? IPPORT_SMTP : atoi(argv[1]);
SSmtp = socket(AF_INET,SOCK_STREAM,0);
bind(SSmtp,(char *)&lsocket,SOCKSIZE);
listen(SSmtp,1);
for(;;){
if((s = accept(SSmtp,NULLCHAR,0)) == -1) {
/* Service is shutting down */
break;
}
if(availmem()) {
/* 421 Spawn a server */
newproc("SMTP server",3072,smtpserv,s,0,0,0);
} else {
shutdown(s,1);
}
}
return 0;
}
#if(defined(MODEM) && defined(ASY))
/* Start mailbox on serial line */
int
tip1(int argc,char **argv,void *p)
{
struct iface *ifp;
struct tipcb *tip;
struct mbuf *bp;
struct usock *up0, *up1;
char *buf[2];
int c, cmd, s[2];
if((ifp = if_lookup(argv[1])) == NULLIF){
tprintf(Badif,argv[1]);
return 1;
}
if(ifp->dev >= ASY_MAX || Asy[ifp->dev].iface != ifp ) {
tprintf(Badasy,argv[1]);
return -1;
}
if(ifp->raw == bitbucket) {
tprintf(TActive,argv[1]);
return 1;
}
psignal(Curproc,0); /* Don't keep the parser waiting */
sprintf(Curproc->name,"Tip listener");
tip = (struct tipcb *)mxallocw(sizeof(struct tipcb));
tip->next = Tiplist;
Tiplist = tip;
/* Save output handler and temporarily redirect output to null */
tip->rawsave = ifp->raw;
ifp->raw = bitbucket;
tip->iface = ifp;
tip->proc = Curproc;
tip->timer.func = tipidle;
tip->timer.arg = (void *)tip;
buf[1] = ifp->name;
/* Suspend packet input drivers */
suspend(ifp->proc);
for(;;) {
/* Wait for DCD to be asserted */
get_rlsd_asy(ifp->dev,1);
if((s[0] = socket(AF_LOCAL,SOCK_STREAM,0)) == -1) {
tputs(Nosocket);
return tip0(2,buf,p);
}
if((s[1] = socket(AF_LOCAL,SOCK_STREAM,0)) == -1) {
close_s(s[0]);
tputs(Nosocket);
return tip0(2,buf,p);
}
up0 = itop(s[0]);
seteol(s[0],"\n");
up1 = itop(s[1]);
seteol(s[1],"\n");
up1->cb.local->peer = up0;
up0->cb.local->peer = up1;
tip->echo = WONT;
tip->s = s[0];
newproc("MBox (Modem)",MSTACKSIZE,mbx_incom,s[1],(void *)TIP,0,0);
set_timer(&tip->timer,Tiptimeout * 1000);
start_timer(&tip->timer);
/*
setflush(tip->s,-1);
sockmode(tip->s,SOCK_ASCII);
*/
/* Now fork into two paths, one rx, one tx */
tip->in = newproc("MBox (Modem in)",256,tip_in,ifp->dev,(void *)TIP,0,0);
while((c = recvchar(tip->s)) != -1) {
if(c == IAC) { /* ignore most telnet options */
if((cmd = recvchar(tip->s)) == -1) {
break;
}
if(cmd > 250 && cmd < 255) {
if((c = recvchar(tip->s)) == -1) {
break;
}
switch(cmd){
case WILL:
if(c == TN_ECHO) {
tip->echo = cmd;
cmd = DO;
} else {
cmd = DONT;
}
break;
case WONT:
if(c == TN_ECHO) {
tip->echo = cmd;
}
cmd = DONT;
break;
case DO:
case DONT:
cmd = WONT;
break;
}
usprintf(tip->s,"%c%c%c",IAC,cmd,c);
usflush(tip->s);
}
continue;
}
if(c == '\n') {
bp = qdata("\r\n",2);
} else {
bp = pushdown(NULLBUF,1);
*bp->data = c;
}
asy_send(ifp->dev,bp);
ifp->lastsent = secclock();
}
close_s(tip->s);
killproc(tip->in);
tip->in = NULLPROC;
pwait(itop(s[1])); /* let mailbox terminate, if necessary */
stop_timer(&tip->timer);
/* Tell line to go down */
ifp->ioctl(ifp,PARAM_DOWN,TRUE,0L);
/* Wait for DCD to be dropped */
get_rlsd_asy(ifp->dev,0);
}
}
#endif
int
ttyl1(int argc,char **argv,void *p)
{
struct sockaddr_in lsocket;
int s;
if(STtylink != -1) {
return 0;
}
psignal(Curproc,0); /* Don't keep the parser waiting */
chpname(Curproc,"TTYlink listener");
lsocket.sin_family = AF_INET;
lsocket.sin_addr.s_addr = INADDR_ANY;
lsocket.sin_port = (argc < 2) ? IPPORT_TTYLINK : atoi(argv[1]);
STtylink = socket(AF_INET,SOCK_STREAM,0);
bind(STtylink,(char *)&lsocket,SOCKSIZE);
listen(STtylink,1);
for(;;) {
if((s = accept(STtylink,NULLCHAR,0)) == -1) {
/* Service is shutting down */
break;
}
if(availmem()) {
/* Spawn a server */
newproc("Chat",1024,ttylhandle,s,(void *)TELNET,0,0);
} else {
shutdown(s,1);
}
}
return 0;
}
/* Start up time server */
int
time1(int argc,char **argv,void *p)
{
struct sockaddr_in lsocket;
int s;
if(STime != -1){
return 0;
}
psignal(Curproc,0); /* Don't keep the parser waiting */
chpname(Curproc,"Time listener");
lsocket.sin_family = AF_INET;
lsocket.sin_addr.s_addr = INADDR_ANY;
lsocket.sin_port = IPPORT_TIME;
STime = socket(AF_INET,SOCK_STREAM,0);
bind(STime,(char *)&lsocket,sizeof(lsocket));
listen(STime,1);
for(;;) {
if((s = accept(STime,NULLCHAR,0)) == -1) {
/* Service is shutting down */
break;
}
if(availmem()) {
/* Spawn a server */
newproc("Time",512,timeserv,s,0,0,0);
} else {
shutdown(s,1);
}
}
return 0;
}
/* ---------------------- Server stop functions ----------------------- */
/* Stop discard server */
int
dis0(int argc,char **argv,void *p)
{
close_s(SDisc);
SDisc = -1;
return 0;
}
/* stop echo server */
int
echo0(int argc,char **argv,void *p)
{
close_s(SEcho);
SEcho = -1;
return 0;
}
#if (defined MAILBOX) && (defined AX25)
int
ax25stop(int argc,char **argv,void *p)
{
close_s(Axi_sock);
Axi_sock = -1;
return 0;
}
#endif
#if (defined MAILBOX) && (defined NETROM)
int
nr4stop(int argc,char **argv,void *p)
{
close_s(SNetrom);
SNetrom = -1;
return 0;
}
#endif
#ifdef MAILBOX
/* Stop telnet server */
int
telnet0(int argc,char **argv,void *p)
{
close_s(STelnet);
STelnet = -1;
return 0;
}
#endif
#ifdef UDP
int
rem0(int argc,char **argv,void *p)
{
close_s(SRem);
SRem = -1;
return 0;
}
#endif
/* Stop convers server */
#ifdef CONVERS
int
conv0(int argc,char **argv,void *p)
{
if(SConv != -1) {
#ifdef LINK
#ifdef LZW
if(SXConv == -1) {
if(Permlink) {
killproc(child);
}
child = NULLPROC;
xfree(CHostname);
}
#else
if(Permlink) {
killproc(child);
}
child = NULLPROC;
xfree(CHostname);
#endif
#endif
close_s(SConv);
SConv = -1;
}
return 0;
}
#endif
#if (defined CONVERS) && (defined LZW)
/* Stop xconvers server */
int
xconv0(int argc,char **argv,void *p)
{
if(SXConv != -1) {
#ifdef LINK
if(SConv == -1) {
if(Permlink) {
killproc(child);
}
child = NULLPROC;
xfree(CHostname);
}
#endif
close_s(SXConv);
SXConv = -1;
}
return 0;
}
#endif
#ifdef DNS
int
dom0(int argc,char **argv,void *p)
{
close_s(SDomain);
SDomain = -1;
return 0;
}
#endif
int
fin0(int argc,char **argv,void *p)
{
close_s(SFinger);
SFinger = -1;
return 0;
}
/* Shut down FTP server */
int
ftp0(int argc,char **argv,void *p)
{
close_s(SFtp);
SFtp = -1;
return 0;
}
#ifdef NNTP
/* Shutdown NNTP service */
int
nntp0(int argc,char **argv,void *p)
{
close_s(SNntp);
SNntp = -1;
return 0;
}
#endif
#ifdef POP
/* Shutdown POP service */
int
pop0(int argc,char **argv,void *p)
{
close_s(SPop);
SPop = -1;
return 0;
}
#endif
/* Shutdown SMTP service */
int
smtp0(int argc,char **argv,void *p)
{
close_s(SSmtp);
SSmtp = -1;
return 0;
}
#if(defined(MODEM) && defined(ASY))
int
tip0(int argc,char **argv,void *p)
{
struct iface *ifp;
struct tipcb *tip, *tiplast = NULLTIP;
struct proc *proc;
if((ifp = if_lookup(argv[1])) == NULLIF){
tprintf(Badif,argv[1]);
return 1;
}
for(tip = Tiplist; tip != NULLTIP; tiplast = tip, tip = tip->next) {
if(tip->iface == ifp) {
if(tiplast != NULLTIP) {
tiplast->next = tip->next;
} else {
Tiplist = tip->next;
}
proc = tip->proc;
close_s(tip->s);
ifp->raw = tip->rawsave;
resume(ifp->proc);
stop_timer(&tip->timer);
killproc(tip->in);
xfree(tip);
killproc(proc);
return 0;
}
}
return 0;
}
#endif
/* Shut down Ttylink server */
int
ttyl0(int argc,char **argv,void *p)
{
close_s(STtylink);
STtylink = -1;
return 0;
}
/* Stop the time server */
int
time0(int argc,char **argv,void *p)
{
close_s(STime);
STime = -1;
return 0;
}
/* -------------------- various server functions ------------------------ */
#ifdef UDP
/* Check remote password */
static int near
chkrpass(struct mbuf *bp)
{
char lbuf[80];
int16 len = len_p(bp);
if(strlen(Rempass) != len) {
return 0;
}
if(len > 79) {
len = 79;
}
pullup(&bp,lbuf,len);
return (strncmp(Rempass,lbuf,len) == 0);
}
#endif
static void
discserv(int s,void *unused,void *p)
{
struct mbuf *bp;
sockowner(s,Curproc);
log(s,9983,"DISC open");
while(recv_mbuf(s,&bp,0,NULLCHAR,0) > 0) {
free_p(bp);
}
log(s,9983,"DISC close");
close_s(s);
}
static void
echoserv(int s,void *unused,void *p)
{
struct mbuf *bp;
sockowner(s,Curproc);
log(s,9983,"ECHO open");
while(recv_mbuf(s,&bp,0,NULLCHAR,0) > 0) {
send_mbuf(s,bp,0,NULLCHAR,0);
}
log(s,9983,"ECHO close");
close_s(s);
}
static void
fingerserv(int s,void *unused,void *p)
{
char user[LINELEN];
sockowner(s,Curproc);
sockmode(s,SOCK_ASCII);
log(s,9983,"FING open");
if(recvline(s,user,LINELEN) >= 0) {
FILE *fp = NULLFILE;
rip(user);
if(strlen(user) == 0) {
usprintf(s,"%snown users on this system\n",
((fp = dir(Fdir,0)) == NULLFILE) ? "No k" : "K");
} else {
char *file = pathname(Fdir,user);
char *cp = pathname(Fdir,"");
/* Check for attempted security violation (e.g., somebody
* might be trying to finger "../ftpusers"!)
*/
if(strncmp(file,cp,strlen(cp)) != 0) {
usputs(s,"Invalid user name\n");
} else if((fp = Fopen(file,READ_TEXT,0,0)) == NULLFILE)
usprintf(s,"Unknown user '%s'\n",user);
xfree(cp);
xfree(file);
}
if(fp != NULLFILE) {
sendfile(fp,s,ASCII_TYPE,0x80);
}
}
log(s,9983,"FING close");
close_s(s);
}
/*
* Serve up the time to the connected client
*/
static void
timeserv(int s,void *unused,void *p)
{
struct mbuf *bp;
char datetime[4];
sockmode(s,SOCK_BINARY);
sockowner(s,Curproc);
log(s,9983,"TIME open");
/*
* Change 1970 start time to 1900 start time, and put
* it in network order
*/
put32(datetime,time((time_t *)0)+DIFFTIME);
/* enqueue for transmission */
bp = qdata(datetime,sizeof(int32));
/* Send time data */
send_mbuf(s,bp,0,NULLCHAR,0);
log(s,9983,"TIME close");
close_s(s);
}
static int near
get_perms(char *s)
{
switch(tolower(*s)) {
case 'b': /* bbs */
return BBS;
case 'm': /* mail */
return MAIL;
case 'n': /* news */
return NEWS;
case 'd': /* bbs & mail */
return (BBS | MAIL);
case 'r': /* bbs & news */
return (BBS | NEWS);
case 's': /* mail & news */
return (MAIL | NEWS);
case 't': /* bbs & mail & news */
return (BBS | MAIL | NEWS);
default: /* if someone prefer digits */
return atoi(s);
}
}
/* Subroutine for logging in the different server.
* The buffer path is allocated here and must be freed from the calling
* routine. A 'default' entry can be set in each file.
* Return value: 0 if no permissions found, > 1 if permissions are given.
*/
int16
userlogin(int16 protocol,void *scb,char *ibuf)
{
FILE *fp;
char cp[LINELEN];
int32 perms = 0;
semwait(&SLoginwait,1);
sprintf(cp,"%s/%s.rc",EtcRoot,tcp_port(protocol));
if((fp = Fopen(cp,READ_TEXT,0,0)) != NULLFILE) {
int def = FALSE;
int32 def_perms = 0;
char *def_arg2 = NULLCHAR, *def_arg3 = NULLCHAR;
char arg1[40], arg2[40], arg3[40];
for( ; ;) {
memset(cp,0,LINELEN);
fgets(cp,LINELEN,fp);
/* Comment line */
if(*cp == '#')
continue;
*arg1 = '\0';
*arg2 = '\0';
*arg3 = '\0';
perms = 0;
sscanf(cp,"%s %s %s %ld",arg1,arg2,arg3,&perms);
if(stricmp(arg1,"default") == 0) {
if(def_arg2) xfree(def_arg2);
def_arg2 = strxdup(arg2);
if(def_arg3) xfree(def_arg3);
def_arg3 = strxdup(arg3);
def_perms = perms;
def = TRUE;
} else {
switch(protocol) {
case IPPORT_FTP: {
struct ftpserv *ftp = scb;
if(stricmp(arg1,ftp->username) == 0) {
if(strcmp(arg2,ibuf) == 0) {
ftp->path = strxdup(arg3);
ftp->perms = perms;
goto found;
}
}
if(feof(fp)) {
if(def == TRUE) {
ftp->path = strxdup(def_arg3);
ftp->perms = perms = def_perms;
}
goto found;
}
break;
}
case IPPORT_SMTP: {
if(!stricmp(arg1,ibuf)) {
/* if(strstr(ibuf,arg1)) { */
perms = get_perms(arg2);
goto found;
}
if(feof(fp)) {
if(def == TRUE) {
perms = get_perms(def_arg2);
}
goto found;
}
break;
}
#ifdef POP
case IPPORT_POP: {
struct popserv *pop = scb;
if(stricmp(arg1,pop->username) == 0) {
if(strcmp(arg2,ibuf) == 0) {
perms = 1;
if(*arg3 == '\0') {
pop->path = mxallocw(MAXPATH);
sprintf(pop->path,"%s/%.8s.txt",Mailspool,pop->username);
} else {
pop->path = strxdup(arg3);
}
goto found;
}
}
if(feof(fp)) {
if(def == TRUE) {
perms = 1;
if(*def_arg3 != '\0') {
pop->def = TRUE;
pop->path = strxdup(def_arg3);
} else {
perms = 0;
}
}
goto found;
}
break;
}
#endif
#ifdef MAILBOX
case IPPORT_TELNET: {
struct mbx *m = scb;
if(stricmp(arg1,m->name) == 0) {
m->path = strxdup(arg3);
m->perms = perms;
if(m->family == AF_AX25
|| m->family == AF_NETROM) {
;
} else {
if(strcmp(arg2,ibuf)) {
m->perms = perms = 0;
}
}
goto found;
}
if(feof(fp)) {
if(def == TRUE) {
m->path = strxdup(def_arg3);
m->perms = perms = def_perms;
}
goto found;
}
break;
}
/* new mailbox */
case 9980: {
struct user *user = scb;
if(stricmp(arg1,ibuf) == 0) {
perms = 1;
if(user) {
strcpy(user->line,arg2);
}
goto found;
}
if(feof(fp)) {
goto found;
}
break;
}
#else
case IPPORT_TELNET:
#endif
case IPPORT_TTYLINK:
case IPPORT_ECHO:
case IPPORT_DISCARD:
case IPPORT_FINGER:
#ifdef NNTP
case IPPORT_NNTP:
#endif
#ifdef CONVERS
case IPPORT_CONVERS:
#ifdef LZW
case IPPORT_XCONVERS:
#endif
#endif
#ifdef DNS
case IPPORT_DOMAIN:
#endif
#ifdef UDP
case IPPORT_REMOTE:
#endif
{
perms = 1;
goto found;
}
}
if(feof(fp))
goto found;
}
}
found:
Fclose(fp);
if(def_arg2) xfree(def_arg2);
if(def_arg3) xfree(def_arg3);
}
semrel(&SLoginwait);
/* Finally return the permission bits */
return perms;
}
#endif /* SERVERS */